package com.labManage.controller;

import com.labManage.dao.PermitionDao;
import com.labManage.dao.UserDao;
import com.labManage.entity.Permition;
import com.labManage.entity.Role;
import com.labManage.entity.User;
import com.labManage.service.UserService;
import com.labManage.util.Md5Util;
import com.labManage.vo.ResultVo;
import com.labManage.vo.UserVo;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.crypto.hash.Md5Hash;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Controller
@RequestMapping("/user")
public class UserController {

    //利用@Autowired注解通过Spring配置文件中的组件扫描器获取userService对象
    @Autowired
    UserService userService = null;

    @Autowired
    HttpServletRequest request;

    @Autowired
    UserDao userDao;

    @Autowired
    PermitionDao permitionDao;
    @RequestMapping("/doSuccess")
    @ResponseBody
    public ResultVo doSuccess(HttpSession session){
        /*将shiro中的身份信息放入到session信息中*/
        Subject subject = SecurityUtils.getSubject();
        User user = (User)subject.getPrincipal();
        session.setAttribute("login_user",user);
        List<Permition> list = permitionDao.getPermitonsByUserId(user.getId());
        session.setAttribute("user_permitions",list);
        return ResultVo.build(0,"登录成功");
    }
    /***************************************************************************************************************************
     *  @fn             login
     *  @brief          用户登录controller方法
     *  @type           非静态方法
     *  @detail         通过接收前端登陆页面的数据作出一系列判断，当参数符合规范时在调用相应的service方法
     *  @param[in]      UserVo uservo   接收前端登录页面的信息，包括学号和密码和验证码
     *  @return         ResultVo        返回登录响应信息，包括响应状态、响应消息、响应数据
     *  @author         杜健华，杜志华
     *  @date           2021.06.18
     ****************************************************************************************************************************/
    @RequestMapping(value = "/doLogin", method = RequestMethod.POST)
    @ResponseBody
    public ResultVo login(UserVo uservo, HttpServletRequest request,HttpServletResponse response) throws IOException {
        String exceptionName = "";
        if(null!=request.getAttribute("shiroLoginFailure")){
            exceptionName = request.getAttribute("shiroLoginFailure").toString();
        }
        if (exceptionName.equals(UnknownAccountException.class.getName())){
            return ResultVo.build(201,"用户名不正确");
        }else if(exceptionName.equals(IncorrectCredentialsException.class.getName())){
            return ResultVo.build(201,"密码不正确");
        }else if(exceptionName.equals("verificationCodeErr")){
            return ResultVo.build(201,"验证码错误");
        }else{
            return ResultVo.build(201,"登录失败");
        }
    }

    /***************************************************************************************************************************
     *  @fn             register
     *  @brief          用户注册controller方法
     *  @type           非静态方法
     *  @detail         通过接收前端注册页面的数据作出一系列判断，当参数符合规范时在调用相应的service方法
     *  @param[in]      UserVo userVo   接收前端注册页面的一系列信息，包括姓名、密码、确认密码、学号、邮箱、手机号
     *  @return         ResultVo        返回登录响应信息，包括响应状态、响应消息、响应数据
     *  @author         杜健华，杜志华
     *  @date           2021.06.18
     ****************************************************************************************************************************/
    @RequestMapping("/register")
    @ResponseBody
    public ResultVo register(UserVo userVo){
        //输入正则表达式，得到一个Pattern对象
        Pattern patternEmail = Pattern.compile("^\\w+([-+.]\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*$");
        Pattern patternPhone = Pattern.compile("^(13[0-9]|14[5|7]|15[0|1|2|3|4|5|6|7|8|9]|18[0|1|2|3|5|6|7|8|9])\\d{8}$");
        //判断是否接收到了前端注册页面的数据，若接收到了，则继续判断
        if(null!=userVo){
            //判断用户名是否为空，若不为空则继续判断密码
            if(true == "".equals(userVo.getUsername().trim())){
                return ResultVo.build(201,"请输入用户名");
            }
            //判断密码是否为空，若不为空，则继续判断确认密码
            if(true=="".equals(userVo.getPassword().trim())){
                return ResultVo.build(201,"请输入密码");
            }
            //判断确认密码是否与密码相同，若相同，则继续判断学号
            if(false==userVo.getPassword().trim().equals(userVo.getPasswordSure().trim())){
                return ResultVo.build(201,"两次密码不一致");
            }
            //判断学号是否为空，若不为空，则继续判断邮箱
            if(true=="".equals(userVo.getUserNo().trim())){
                return ResultVo.build(201,"请输入学号");
            }
            //传入需要正则匹配的字符串，得到Matcher对象
            Matcher matcherEmail =  patternEmail.matcher(userVo.getEmail().trim());
            Matcher matcherPhone = patternPhone.matcher(userVo.getPhone().trim());
            String matcherResult = null;
            //判断邮箱是否为空，若不为空，在进行正则匹配
            if(false=="".equals(userVo.getEmail().trim())){
                //逐次向后匹配邮箱，直到不能匹配为止，最后得到匹配到的字符串
                while(matcherEmail.find()){
                    matcherResult = matcherEmail.group();
                }
                //判断邮箱格式是否正确，若正确，继续判断手机号
                if(false==userVo.getEmail().trim().equals(matcherResult)){
                    return ResultVo.build(201,"请输入正确的邮箱地址");
                }
            }

            //判断手机号是否为空，若不为空，在进行正则匹配
            if(false=="".equals(userVo.getEmail().trim())){
                //逐次向后匹配手机号，直到不能匹配为止，最后得到匹配到的字符串
                while(matcherPhone.find()){
                    matcherResult = matcherPhone.group();
                }
                //判断手机号格式是否正确，若正确，调用service方法处理业务
                if(false==userVo.getPhone().trim().equals(matcherResult)){
                    return ResultVo.build(201,"请输入正确的手机号");
                }
            }

            //封装掉用service相应的业务方法要用到的参数
            User user = new User();
            user.setUsername(userVo.getUsername());
            user.setPassword(new Md5Hash(userVo.getPassword(), "123", 1).toString());
            user.setUserNo(userVo.getUserNo());
            user.setEmail(userVo.getEmail());
            user.setPhone(userVo.getPhone());
            //调用service相应的业务方法
            int result = userService.register(user);
            //如果service相应的业务方法返回值符合要求，则注册成功
            if(0<result){
                return ResultVo.build(0,"注册成功");
            }else {
                return ResultVo.build(201,"注册失败");
            }
        }else{
            return ResultVo.build(500,"500");
        }
    }

    @RequestMapping("/getLoginUser")
    @ResponseBody
    public ResultVo getLoginUser(HttpServletRequest request){
        HttpSession session = request.getSession();
        //取出session对象中的用户名，显示到页面上
        User login_user = (User)session.getAttribute("login_user");
        if(null!=login_user){
            return ResultVo.build(0,"",login_user);
        }else{
            return ResultVo.build(201,"",null);
        }
    }

    @RequestMapping("/getAllUser")
    @ResponseBody
    public ResultVo getAllUser(Integer page,Integer limit,UserVo condition,String roleIds){
        if(roleIds != null && !roleIds.trim().equals("")){
            String[] array = roleIds.split(",");
            List<Role> roles = new ArrayList<>();
            for (int i = 0; i < array.length; i++) {
                Role role = new Role();
                role.setId(Long.parseLong(array[i]));
                roles.add(role);
            }
            condition.setRoles(roles);
        }

        List<UserVo> allUser = userService.getAllUser(page, limit,condition);
        if(null!=allUser){
            return ResultVo.build(userService.getUserNum(condition),0,"",allUser);
        }else{
            return ResultVo.build(201,"",null);
        }
    }
    @RequestMapping("/getUserInfoById")
    @ResponseBody
    public ResultVo getUserInfoById(){
        Subject subject = SecurityUtils.getSubject();
        User loginUser = (User)subject.getPrincipal();

        User user = userService.getUserInfoById(loginUser.getId());
        if(null!=user){
            return ResultVo.build(0,"",user);
        }else {
            return ResultVo.build(201,"",null);
        }
    }

    @RequestMapping("/commitUserModifyInfo")
    @ResponseBody
    @RequiresPermissions("user:modify")
    public ResultVo commitUserModifyInfo(User user,String roleIds) {
        int result = 0;
        if(null!=user&&roleIds != null && !roleIds.trim().equals("")){
            String[] array = roleIds.split(",");
            List<Long> roles = new ArrayList<>();
            for (int i = 0; i < array.length; i++) {
                roles.add(Long.parseLong(array[i]));
            }
            result = userService.ModifyUserInfo(user,roles);
            if(0<result){
                return ResultVo.build(0,"");
            }else{
                return ResultVo.build(201,"");
            }
        }else {
            return ResultVo.build(500,"");
        }
    }

    @RequestMapping("/deleteUserInfo")
    @ResponseBody
    @RequiresPermissions("user:delete")
    public ResultVo deleteUserInfo(Long id){
        int result = userService.deleteUserInfo(id);
        if(0<result){
            return ResultVo.build(0,"删除成功");
        }else {
            return ResultVo.build(201,"删除失败");
        }
    }

    @RequestMapping("/modifyPassword")
    @ResponseBody
    public ResultVo modifyPassword(Long id,String oldPwd,String newPwd,String username){
        User userInfo = userService.getUserInfoById(id);
        if(null!=userInfo){
            String Md5OldPwd = new Md5Hash(oldPwd, "123", 1).toString();
            if(false==Md5OldPwd.equals(userInfo.getPassword())){
                return ResultVo.build(201,"旧密码输入错误");
            }else {
                int result = userService.updateUserPassword(id,newPwd,username);
                if(0<result){
                    return ResultVo.build(0,"密码修改成功");
                }else {
                    return ResultVo.build(201,"密码修改失败");
                }
            }
        }else {
            return ResultVo.build(500,"");
        }
    }

    @RequestMapping("/initPassword")
    @ResponseBody
    @RequiresPermissions("user:initPwd")
    public ResultVo initPassword(User user){
        int result = userService.initPassword(user);
        if(0<result){
            return ResultVo.build(0,"重置密码成功");
        }else {
            return ResultVo.build(201,"重置密码失败");
        }
    }

    @RequestMapping("/getUserNum")
    @ResponseBody
    public ResultVo getUserNum(){
        long userNum = userDao.selectUserNum(new UserVo());
        return ResultVo.build(0,"",userNum);
    }
}
